﻿package  {
	import IntersectionInfo;
	import flash.display.MovieClip;
	import com.greensock.*;
	import com.greensock.easing.*;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	
	public class Intersection {
		private static const NONE:int = -1;
		private static const LONG_S:int = 0;
		private static const SHORT_S:int = 1;
		private static const GREEN:int = 2;
		private static const YELLOW:int = 1;
		private static const RED:int = 0;
		
		public var inter:MovieClip;
		public var signals:Array; //[[a1,a2],[b1,b2], ...] xD array of signals MovieClip ... x is the num of directions.
		public var arrows:Array; // [ [direction,[a1,a2],[b1,b2]], ...] xD array of Arrows' MC, directions are: u,d,l,r (arrows direction towrads the Signal).
		public var interInfo:IntersectionInfo;
		
		private var nextSequancePos:int;
		private var previousDirection:int;
		private var currentDirection:int;
		private var currentSignals:Array;
		private var currentArrows:Array;
		private var signalTimer:Timer;
		private var intervalTimer:Timer;
		private var currentSignalState:int;
		private var ledsTween:Array; // [[ [R1,R2], [Y1,Y2], [G1,G2] ],[],[],[]]
		private var arrowsTween:Array // [ [[a1,a2,a3], [b1,b2,b3]],  [[], []],  [[], []],  [[], []]] a1 is first arrow in direction 1 to signal direction
									                                                               //  b2 is second arrow in direction 1 opposite to signal direction.
		//=======================================================================//
		//                               Constructor                             //
		//=======================================================================//
		public function Intersection(inter:MovieClip,signals:Array,arrows:Array,interInfo:IntersectionInfo) {
			trace("Constructor");
		}
		
		
		//=======================================================================//
		//                              initTweens                               //
		//=======================================================================//
		private function initTweens():void
		{
			var dir:int;
			for( dir=0; dir<int(interInfo.numOfDirections);dir++)
			{
				var redTweenVars:Object =  {blurFilter:{blurX:5},
							glowFilter:{color:0xff3300, alpha:1, blurX:30, blurY:30, strength:3},
							colorTransform:{tint:0xff3300, tintAmount:0.5, brightness:2}};
				var yellowTweenVars:Object = {paused:true,blurFilter:{blurX:5},
							glowFilter:{color:0xffff00, alpha:1, blurX:30, blurY:30, strength:3},
							colorTransform:{tint:0xffff00, tintAmount:0.7, brightness:2}};
				var greenTweenVars:Object = {paused:true,blurFilter:{blurX:5},
							glowFilter:{color:0x91e600, alpha:1, blurX:30, blurY:30, strength:3},
							colorTransform:{tint:0x33ff00, tintAmount:0.5, brightness:2}};
				ledsTween[dir] = new Array();
				//Red
				ledsTween[dir][RED] = new Array();
				ledsTween[dir][RED][0] = new TweenMax(signals[dir][0].red, .5, redTweenVars);
				if(signals[dir].length > 1)
					ledsTween[dir][RED][1] = new TweenMax(signals[dir][1].red, .5, redTweenVars);
				//Yellow
				ledsTween[dir][YELLOW] = new Array();
				ledsTween[dir][YELLOW][0] = new TweenMax(signals[dir][0].yellow, .5, yellowTweenVars);
				if(signals[dir].length > 1)
					ledsTween[dir][YELLOW][1] = new TweenMax(signals[dir][1].yellow, .5, yellowTweenVars);
				//GREEN
				ledsTween[dir][GREEN] = new Array();
				ledsTween[dir][GREEN][0] = new TweenMax(signals[dir][0].green, .5, greenTweenVars);
				if(signals[dir].length > 1)
					ledsTween[dir][GREEN][1] = new TweenMax(signals[dir][1].green, .5, greenTweenVars);
			}
		//	Arrows
			for(dir = 0; dir<int(interInfo.numOfDirections);dir++)
			{
				var distance:int = 30;
				var laneCounter:int;
				arrowsTween[dir] = new Array();
				arrowsTween[dir][0] = new Array();
				arrowsTween[dir][1] = new Array();
				for(laneCounter = 0;laneCounter < int(interInfo.numOfLanes); laneCounter++)
				{
					var arrowMC:MovieClip;
					if(arrows[dir][0] == "u")
					{
						arrowMC = MovieClip(arrows[dir][1][laneCounter]);
						arrowsTween[dir][0][laneCounter] = new TweenMax(arrowMC,1,{startAt:{autoAlpha:0},y:arrowMC.y-distance,
																		autoAlpha:1,repeat:-1,paused:true});
						arrowMC = MovieClip(arrows[dir][2][laneCounter]);
						arrowsTween[dir][1][laneCounter] = new TweenMax(arrowMC,1,{startAt:{autoAlpha:0},y:arrowMC.y+distance,
																		autoAlpha:1,repeat:-1,paused:true});
					}
					else if(arrows[dir][0] == "d")
					{
						arrowMC = MovieClip(arrows[dir][1][laneCounter]);
						arrowsTween[dir][0][laneCounter] = new TweenMax(arrowMC,1,{startAt:{autoAlpha:0},y:arrowMC.y+distance,
																		autoAlpha:1,repeat:-1,paused:true});
						arrowMC = MovieClip(arrows[dir][2][laneCounter]);
						arrowsTween[dir][1][laneCounter] = new TweenMax(arrowMC,1,{startAt:{autoAlpha:0},y:arrowMC.y-distance,
																		autoAlpha:1,repeat:-1,paused:true});
					}
					else if(arrows[dir][0] == "l")
					{
						arrowMC = MovieClip(arrows[dir][1][laneCounter]);
						arrowsTween[dir][0][laneCounter] = new TweenMax(arrowMC,1,{startAt:{autoAlpha:0},x:arrowMC.x-distance,
																		autoAlpha:1,repeat:-1,paused:true});
						arrowMC = MovieClip(arrows[dir][2][laneCounter]);
						arrowsTween[dir][1][laneCounter] = new TweenMax(arrowMC,1,{startAt:{autoAlpha:0},x:arrowMC.x+distance,
																		autoAlpha:1,repeat:-1,paused:true});
					}
					else
					{
						arrowMC = MovieClip(arrows[dir][1][laneCounter]);
						arrowsTween[dir][0][laneCounter] = new TweenMax(arrowMC,1,{startAt:{autoAlpha:0},x:arrowMC.x+distance,
																		autoAlpha:1,repeat:-1,paused:true});
						arrowMC = MovieClip(arrows[dir][2][laneCounter]);
						arrowsTween[dir][1][laneCounter] = new TweenMax(arrowMC,1,{startAt:{autoAlpha:0},x:arrowMC.x-distance,
																		autoAlpha:1,repeat:-1,paused:true});
					}
				}
			}
			
		}
		//=======================================================================//
		//                             startSimulation                           //
		//=======================================================================//
		public function startSimulation():void
		{
			nextSequancePos = 0;
			initTweens();
			previousDirection = NONE;
			currentDirection = int(interInfo.sequance[nextSequancePos]);
			simulateDirection();
		}
		//=======================================================================//
		//                           simulateDirection                           //
		//=======================================================================//
		private function simulateDirection():void
		{
			startSignalsSim();
			startArrowsSim();
		}
		//=======================================================================//
		//                            simulateSignals                            //
		//=======================================================================//
		private function startSignalsSim():void
		{
			currentSignals = signals[currentDirection-1];
			setCurrentSignals(GREEN,RED);
			signalTimer.start();
		}
		//=======================================================================//
		//                            simulateArrows                             //
		//=======================================================================//
		private function startArrowsSim():void
		{
			setCurrentArrows(currentDirection,previousDirection);
		}
		//=======================================================================//
		//                          setCurrentSignals                            //
		//=======================================================================//
		private function setCurrentSignals(colorToActivate:int,colorToDeactivate:int):void
		{
			currentSignalState = colorToActivate;
			//DeActivate
			if(colorToDeactivate != NONE)
			{
				ledsTween[currentDirection-1][colorToDeactivate][0].reverse();
				if(currentSignals.length > 1)
					ledsTween[currentDirection-1][colorToDeactivate][1].reverse();
			}
			//Activate
			if(colorToActivate != NONE)
			{
				ledsTween[currentDirection-1][currentSignalState][0].play();
				if(currentSignals.length > 1)
					ledsTween[currentDirection-1][currentSignalState][1].play();
			}
		}
		//=======================================================================//
		//                          setCurrentArrows                             //
		//=======================================================================//
		private function setCurrentArrows(dirToActivate:int,dirToDeactivate:int):void
		{
			var laneCounter:int;
			for(laneCounter = 0; dirToDeactivate!=NONE && laneCounter < int(interInfo.numOfLanes); laneCounter++)
			{
				arrowsTween[dirToDeactivate-1][0][laneCounter].pause();
				arrowsTween[dirToDeactivate-1][1][laneCounter].pause();
			}
			for(laneCounter = 0; dirToActivate!= NONE && laneCounter < int(interInfo.numOfLanes); laneCounter++)
			{
				arrowsTween[dirToActivate-1][0][laneCounter].play();
				arrowsTween[dirToActivate-1][1][laneCounter].play();
			}
		}
		//=======================================================================//
		//                          signalTimerHandler                           //
		//=======================================================================//
		private function signalTimerHandler(event:TimerEvent):void
		{
			if(currentSignalState == GREEN)
			{
				setCurrentSignals(YELLOW,GREEN);
				signalTimer.start();
			}
			else if(currentSignalState == YELLOW)
			{
				setCurrentSignals(RED,YELLOW);
				if(nextSequancePos < interInfo.sequance.length-1)
					nextSequancePos++;
				else
					nextSequancePos = 0;
				previousDirection = currentDirection;
				currentDirection = int(interInfo.sequance[nextSequancePos]);
				intervalTimer.start();
			}
		}
		//=======================================================================//
		//                          intervalTimerHandler                         //
		//=======================================================================//
		private function intervalTimerHandler(event:TimerEvent):void
		{
			simulateDirection();
		}
	}
	
}
